package com.mapforge.gui.frames.tilelayer;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.mapforge.listener.TileLayerCreationEvent;
import com.mapforge.listener.TileLayerCreationListener;
import com.mapforge.map.TileLayer;
import com.mapforge.map.TileMap;

public class NewTileLayerDialog extends JDialog {

	/**
	 * Default serial version ID, here to remove warnings
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * Listeners interested in tile layer creation events
	 */
	private List<TileLayerCreationListener> tileLayerListeners;

	private ActionListener tileLayerActionListener;
	private KeyListener tileLayerKeyListener;

	private TileMap tileMap;

	// GUI objects
	private JTextField txtTileLayerName;
	private JButton okBtn;
	private JButton cancelBtn;

	protected NewTileLayerDialog(JFrame parent,
			List<TileLayerCreationListener> listeners, TileMap tileMap) {
		super(parent, "New Tile Layer", true);
		this.tileLayerListeners = listeners;
		initGUI();
		setFocusable(true);
		createGUILayout();
		this.setResizable(false);
		this.tileMap = tileMap;
	}

	private TileLayer createTileLayer() {
		return new TileLayer(txtTileLayerName.getText(), tileMap.getTileset(),
				tileMap.getTotalHorizontalTiles(), tileMap
						.getTotalVerticalTiles());
	}

	private void initGUI() {
		tileLayerActionListener = new TileLayerActionListener();
		tileLayerKeyListener = new NewTileLayerKeyListener();

		txtTileLayerName = new JTextField(20);
		txtTileLayerName.addActionListener(tileLayerActionListener);
		txtTileLayerName.addKeyListener(tileLayerKeyListener);
		okBtn = new JButton("OK");
		okBtn.setEnabled(false);
		okBtn.addActionListener(tileLayerActionListener);
		cancelBtn = new JButton("Cancel");
		cancelBtn.addActionListener(tileLayerActionListener);
	}

	private void createGUILayout() {
		JPanel txtNamePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2));
		JPanel btnControlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
				2, 2));

		txtNamePanel.add(new JLabel("Layer Name:"));
		txtNamePanel.add(txtTileLayerName);

		btnControlPanel.add(okBtn);
		btnControlPanel.add(cancelBtn);

		add(txtNamePanel, BorderLayout.CENTER);
		add(btnControlPanel, BorderLayout.SOUTH);
		pack();
	}

	private class TileLayerActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			Object src = e.getSource();
			if (src == okBtn || src == txtTileLayerName) {
				if (txtTileLayerName.getText().equals("")) {
					JOptionPane.showMessageDialog(NewTileLayerDialog.this,
							"All tile layers must have a name.");
					return;
				}
				TileLayer tileLayer = createTileLayer();
				fireTileLayerCreatedEvent(tileLayer);
				clearFieldsAndClose();
			} else if (src == cancelBtn) {
				clearFieldsAndClose();
			}
		}
	}

	private void fireTileLayerCreatedEvent(TileLayer layer) {
		TileLayerCreationEvent event = new TileLayerCreationEvent(this, layer);
		for (int i = 0; i < tileLayerListeners.size(); i++) {
			tileLayerListeners.get(i).tileLayerCreationPerformed(event);
		}
	}

	public void setVisible(boolean val) {
		if (val) {
			pack();
			this.setLocationRelativeTo(getParent());
			txtTileLayerName.requestFocus();
		}
		super.setVisible(val);
	}

	private void clearFieldsAndClose() {
		txtTileLayerName.setText("");
		okBtn.setEnabled(false);
		setVisible(false);
	}

	private class NewTileLayerKeyListener implements KeyListener {
		public void keyPressed(KeyEvent e) {
			okBtn.setEnabled(!txtTileLayerName.getText().equals(""));
		}

		public void keyTyped(KeyEvent e) {
			okBtn.setEnabled(!txtTileLayerName.getText().equals(""));
		}

		public void keyReleased(KeyEvent e) {
			okBtn.setEnabled(!txtTileLayerName.getText().equals(""));
		}
	}
}